package com.architecture.util.bool;

import com.architecture.util.number.NumberUtility;
import com.architecture.util.object.ObjectUtility;

/**
 * <p>This class has utilities methods for be used with Logical Operations.</p>
 * @author JR
 * @version 1.0
 * @category Boolean Utilities
 */
public final class BooleanUtility {
	
	/**
	 * private constructor of <code>BooleanUtility</code>.
	 */
	private BooleanUtility() {
		super();
	}
	
	/**
	 * <p>Verifies if the expression has only true values.</p>
	 * @param expressions
	 * @return Boolean
	 */
	public static Boolean and(final Boolean...expressions){
		Boolean and = Boolean.TRUE;
		if(ObjectUtility.isRef(expressions)){
			final int size = expressions.length;
			if(NumberUtility.gt(size, 0)){
				for(final Boolean expr:expressions){
					if(!expr.booleanValue()){
						and = Boolean.FALSE;
						break;
					}
				}
				return and;
			}else{
				return Boolean.FALSE;
			}
		}else{
			throw new NullPointerException();	
		}
	}
	
	/**
	 * <p>Verifies if the two expression using logical operator <code>and</code>.</p>
	 * @param arg0
	 * @param arg1
	 * @return Boolean
	 */
	public static Boolean and(final Boolean arg0, final Boolean arg1){
		if(ObjectUtility.isAllRef(arg0,arg1)){
			return arg0 && arg1;
		}else{
			throw new NullPointerException();	
		}
	}
	
	/**
	 * <p>Verifies if the expression has only one true value.</p>
	 * @param expressions
	 * @return Boolean
	 */
	public static Boolean or(final Boolean...expressions){
		Boolean or = Boolean.FALSE;
		if(ObjectUtility.isRef(expressions)){
			final int size = expressions.length;
			if(NumberUtility.gt(size, 0)){
				for(final Boolean expr:expressions){
					if(expr.booleanValue()){
						or = Boolean.TRUE;
						break;
					}
				}
				return or;
			}else{
				return Boolean.FALSE;
			}
		}else{
			throw new NullPointerException();	
		}
	}
	
	/**
	 * <p>Verifies if the two expression using logical operator <code>or</code>.</p>
	 * @param arg0
	 * @param arg1
	 * @return Boolean
	 */
	public static Boolean or(final Boolean arg0,final Boolean arg1){
		if(ObjectUtility.isAllRef(arg0,arg1)){
			return arg0 || arg1;
		}else{
			throw new NullPointerException();
		}
	}
	
	/**
	 * <p>Makes the expression the inverse form using logical operator <code>not</code>.</p>
	 * @param arg0
	 * @return <code>Boolean</code>
	 */
	public static Boolean not(final Boolean arg0){
		if(ObjectUtility.isRef(arg0)){
			return ( arg0 ? Boolean.FALSE : Boolean.FALSE );
		}else{
			throw new NullPointerException();
		}
	}
	
}
